/**
 1.多线程共享数据
 再多线程的操作中，多个线程有可能同时处理同一个资源，这就是多线程中的共享数据。
 2.线程同步
 解决数据共享问题，必须使用同步，所谓同步就是指多个线程再同一个时间段内只能有一个线程执行指定代码，
 其他线程要等待此线程完成之后才可以继续执行。
 线程进行同步，有以下三种方法
 1.同步代码块
 synchronized（要同步的对象）{
    要同步的操作;
 }
 2.同步方法
 public synchronized void method(){
    要同步的操作;
 }
 3.Lock(ReentrantLock)

 */

/*
package 第十章_多线程与并发;

import com.sun.org.apache.bcel.internal.generic.GOTO;

import java.util.concurrent.locks.ReentrantLock;

import static java.lang.Thread.sleep;

public class U10_L6_线程同步 {
    public static void main(String[] args) {
        run();
    }

    private static void run() {
        MyThread mt = new MyThread();
        Thread t1 = new Thread(mt);
        Thread t2 = new Thread(mt);
        Thread t3=new Thread(mt);

        t2.setName("No.1 pp ");
        t1.setName("No.2 tt ");
        t3.setName("No.3 dd ");
        t1.setPriority(10);
        t2.setPriority(5);
        t1.start();
        t2.start();
        t3.start();


    }
}
class MyThread implements Runnable{
    private int tickets=10;
    ReentrantLock lock=new ReentrantLock();
    boolean flag=false;
    public void run(){
        out:
            while(!flag) {
                int count=tickets;
                for (int i = 0;i<(count<<1); i++) {
                    //synchronized 是同步 代码块 里面是对象 可以自定义一个对象也可以把当前this 当对象使用 同步就是共用部分
                    synchronized (this) {
                        if(tickets>0) {
                            tickets--;
                            System.out.println(Thread.currentThread().getName() + "--times: " + (i + 1)
                                    + "\n票数余额还剩: " + tickets + "张" );
                            try {
                                sleep(1);
                            } catch (InterruptedException e) {
                                throw new RuntimeException(e);
                            }
                            if(tickets==0) {
                                flag = true;
                                System.out.println("flag状态: " + flag + " 跳出循环...");
                                break out;
                            }
                        }else{
                            System.out.println("flag状态: "+flag+" 跳出循环...");
                            break out;
                        }
                    }
                }
            }
        System.out.println(Thread.currentThread().getName()+"over");


            //case_1();
            //case_2();
    }

    //synchronized 第二种方法  使用此词根封装
    private synchronized void case_1(){
        while(tickets!=0) {
            if (tickets > 0) {
                tickets--;
                System.out.println(Thread.currentThread().getName() + "--times: "
                        + "\n票数余额还剩: " + tickets + "张");
                try {
                    sleep(10);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        System.out.println(Thread.currentThread().getName()+"over");
    }

    //使用lock 对象要写在类里面
    public void case_2(){
        lock.lock();
        System.out.println("----lock.lock()-------");
        while(tickets!=0) {
            if (tickets > 0) {
                tickets--;
                System.out.println(Thread.currentThread().getName() + "--times: "
                        + "\n票数余额还剩: " + tickets + "张");
                try {
                    sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        System.out.println(Thread.currentThread().getName()+"over");
        lock.unlock();
    }
}

 */
